/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.icee.myth.server.quest;

import com.icee.myth.config.MapConfig;
import com.icee.myth.log.GameLogger;
import com.icee.myth.log.message.FileDebugGameLogMessage;
import com.icee.myth.log.message.GameLogMessage.GameLogType;
import com.icee.myth.log.message.builder.GameLogMessageBuilder;
import com.icee.myth.protobuf.ExternalCommonProtocol.QuestProto;
import com.icee.myth.protobuf.ExternalCommonProtocol.QuestsProto;
import com.icee.myth.protobuf.builder.ClientToMapBuilder;
import com.icee.myth.server.actor.Human;
import com.icee.myth.utils.Consts;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;

/**
 *
 * @author liuxianke
 */
public class Quests {
    public final Human human;
    
    // 已接过关任务列表
    public TreeMap<Integer, Quest> stageQuests;
    // 已接升级任务列表
    public TreeMap<Integer, Quest> levelQuests;

    public Quests(Human human, QuestsProto questsProto) {
        this.human = human;

        if (questsProto != null) {
            List<QuestProto> questProtos = questsProto.getQuestsList();
            for (QuestProto questProto : questProtos) {
                int questId = questProto.getQuestId();
                QuestStaticInfo staticInfo = QuestsConfig.INSTANCE.getQuestStaticInfo(questId);
                if (staticInfo != null) {
                    Quest quest = new Quest(human, staticInfo);
                    quest.finished = questProto.getFinished();
                    addAppliedQuest(quest);
                }
            }
        } else {
            QuestStaticInfo staticInfo = QuestsConfig.INSTANCE.getQuestStaticInfo(MapConfig.INSTANCE.initQuestId);
            Quest quest = new Quest(human, staticInfo);
            addAppliedQuest(quest);
        }
    }

    public QuestsProto buildQuestsProto() {
        QuestsProto.Builder builder = QuestsProto.newBuilder();

        if (stageQuests != null) {
            for (Quest quest : stageQuests.values()) {
                builder.addQuests(quest.buildQuestProto());
            }
        }

        if (levelQuests != null) {
            for (Quest quest : levelQuests.values()) {
                builder.addQuests(quest.buildQuestProto());
            }
        }

        return builder.build();
    }

    private void addAppliedQuest(Quest quest) {
        QuestStaticInfo staticInfo = quest.staticInfo;
        switch (staticInfo.type) {
            case Consts.QUEST_TYPE_STAGE: {
                if (stageQuests == null) {
                    stageQuests = new TreeMap<Integer, Quest>();
                }

                // 若关卡已经通过则将任务设为已完成
                if ((!staticInfo.isBigStage && (human.stages.currentNormalStageId>staticInfo.value1)) ||
                    (staticInfo.isBigStage && (human.stages.currentBigStageId>staticInfo.value1))) {
                    quest.finished = true;
                }

                stageQuests.put(staticInfo.id, quest);
                break;
            }
            case Consts.QUEST_TYPE_LEVEL: {
                if (levelQuests == null) {
                    levelQuests = new TreeMap<Integer, Quest>();
                }

                // 若等级已达到任务目标等级，将任务状态改为已完成
                if (human.lv >= staticInfo.value1) {
                    quest.finished = true;
                }

                levelQuests.put(staticInfo.id, quest);
                break;
            }
            default: {
                GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                        FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                        "Player[" + human.id + "] can't init Quest[" + staticInfo.id + "] because unknown quest type[" + staticInfo.type + "]."));
            }
        }
    }

    private Quest getAppliedQuest(QuestStaticInfo questStaticInfo) {
        switch (questStaticInfo.type) {
            case Consts.QUEST_TYPE_STAGE: {
                if (stageQuests != null) {
                    return stageQuests.get(questStaticInfo.id);
                }
                break;
            }
            case Consts.QUEST_TYPE_LEVEL: {
                if (levelQuests != null) {
                    return levelQuests.get(questStaticInfo.id);
                }
                break;
            }
            default: {
                GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                        FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                        "Unknown quest[" + questStaticInfo.id + "] type[" + questStaticInfo.type + "]."));
                break;
            }
        }
        return null;
    }

    // 注意：在调用removeAppliedQuest前已经能确定quest存在
    private void removeAppliedQuest(Quest quest) {
        QuestStaticInfo staticInfo = quest.staticInfo;
        switch (staticInfo.type) {
            case Consts.QUEST_TYPE_STAGE: {
                stageQuests.remove(staticInfo.id);

                if (stageQuests.isEmpty()) {
                    stageQuests = null;
                }
                break;
            }
            case Consts.QUEST_TYPE_LEVEL: {
                levelQuests.remove(staticInfo.id);

                if (levelQuests.isEmpty()) {
                    levelQuests = null;
                }
                break;
            }
            default: {
                GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                        FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                        "Unknown quest[" + staticInfo.id + "] type[" + staticInfo.type + "]."));
                break;
            }
        }
    }

    public void submit(int questId) {
        // 判断任务是否已接取
        QuestStaticInfo questStaticInfo = QuestsConfig.INSTANCE.getQuestStaticInfo(questId);
        if (questStaticInfo != null) {
            Quest quest = getAppliedQuest(questStaticInfo);
            if (quest != null) {
                // 判断任务是否已完成
                if (quest.finished) {
                    // 领取任务奖励
                    human.digestCertainReward(questStaticInfo.reward, Consts.SOUL_CHANGE_LOG_TYPE_QUEST, questId);

                    // 交任务
                    removeAppliedQuest(quest);
                    
                    human.sendMessage(ClientToMapBuilder.buildQuestSubmitted(questId));

                    // 开启后续任务
                    if ((questStaticInfo.nextQuests != null) && (questStaticInfo.nextQuests.length > 0)) {
                        LinkedList<Quest> newQuests = new LinkedList<Quest>();
                        for (int nextQuestId : questStaticInfo.nextQuests) {
                            QuestStaticInfo newQuestStaticInfo = QuestsConfig.INSTANCE.getQuestStaticInfo(nextQuestId);
                            Quest newQuest = new Quest(human, newQuestStaticInfo);
                            addAppliedQuest(newQuest);

                            newQuests.add(newQuest);
                        }

                        human.sendMessage(ClientToMapBuilder.buildQuestAddList(newQuests));
                    }

                    // 记录行为日志
                    if (MapConfig.INSTANCE.useCYLog == true) {
                        List<String> cyLogList = new ArrayList<String>();
                        cyLogList.add("taskMC");
                        cyLogList.add(String.valueOf(MapConfig.INSTANCE.gameId));
                        cyLogList.add("KDTY");
                        cyLogList.add(String.valueOf(human.id));
                        cyLogList.add(human.name);
                        cyLogList.add("");
                        cyLogList.add(String.valueOf(questId));
                        cyLogList.add("");
                        cyLogList.add("");
                        cyLogList.add("");
                        cyLogList.add("");
                        cyLogList.add("");
                        cyLogList.add("");
                        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileCYGameLogMessage(cyLogList, GameLogType.GAMELOGTYPE_CY_TASK));

                        cyLogList = new ArrayList<String>();
                                cyLogList.add("behaviorMC");
                                cyLogList.add(String.valueOf(MapConfig.INSTANCE.gameId));
                                cyLogList.add("KDTY");
                                cyLogList.add(String.valueOf(human.id));
                                cyLogList.add(human.name);
                                cyLogList.add("");
                                cyLogList.add("SubmitQuestDBBehavior");
                                cyLogList.add(questId + " ");
                                cyLogList.add("");
                                cyLogList.add("");
                                cyLogList.add("");
                                cyLogList.add("");
                                cyLogList.add("");
                                GameLogger.getlogger().log(GameLogMessageBuilder.buildFileCYGameLogMessage(cyLogList, GameLogType.GAMELOGTYPE_CY_BEHAVIOR));
                    }
                    GameLogger.getlogger().log(GameLogMessageBuilder.buildSubmitQuestDBBehaviorGameLogMessage(human.id, questId));
                } else {
                    GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                            FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                            "Player[" + human.id + "] can't submit Quest[" + questId + "] because it isn't finished."));
                }
            } else {
                GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                        FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                        "Player[" + human.id + "] can't submit Quest[" + questId + "] because haven't applied."));
            }
        } else {
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                    "Player[" + human.id + "] can't submit Quest[" + questId + "] because quest info not found."));
        }
    }

    // 升级
    public void levelup(int level) {
        if (levelQuests != null) {
            for (Quest quest : levelQuests.values()) {
                if (quest.staticInfo.type == Consts.QUEST_TYPE_LEVEL) {
                    quest.levelup(level);
                } else {
                    GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                            FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                            "Player[" + human.id + "] level up quests list contain wrong quest[" + quest.staticInfo.id + "]."));
                }
            }
        }
    }

    // 过关
    public void finishState(int stageId, boolean isBigStage, boolean needSend) {
        if (stageQuests != null) {
            for (Quest quest : stageQuests.values()) {
                if (quest.staticInfo.type == Consts.QUEST_TYPE_STAGE) {
                    quest.finishStage(stageId, isBigStage, needSend);
                } else {
                    GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                            FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                            "Player[" + human.id + "] finish stage quests list contain wrong quest[" + quest.staticInfo.id + "]."));
                }
            }
        }
    }
}
